package com.hisoft.xml;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.log4j.Logger;

import com.hisoft.constant.XMLTestCaseTag;
import com.hisoft.entity.ABaseTag;
import com.hisoft.entity.Assert;
import com.hisoft.entity.Function;
import com.hisoft.entity.Html;
import com.hisoft.entity.Verify;
import com.hisoft.exception.XpathNotFoundException;
import com.hisoft.type.AssertVerifyType;
import com.hisoft.utility.CommonTool;
import com.hisoft.utility.DataProviderTool;

public class XML2Import {
	private static Logger logger = Logger.getLogger(XML2Import.class);
	private static XMLInputFactory factory = XMLInputFactory.newInstance();
	private static XMLStreamReader reader;
	private static String fileName;
	private static final String srcPath = "import/";

	/**
	 * 把xml对象封装成import对象 <b> </b>
	 * 
	 * @Author chenyue ( yue.chen2@hisoft.com ) Create on 2011-6-17
	 */
	public static List<ABaseTag> xml2Import(String str) {
		File file = new File(srcPath + str);
		if (!file.exists()) {
			FileNotFoundException ffe = new java.io.FileNotFoundException(file.getPath());
			logger.error(ffe.getMessage(), ffe);
		}
		return xml2Import(file);
	}

	/**
	 * 
	 * <b> </b> 封装import xml对象，处理 html verify assert function 标签
	 * 
	 * @Author chenyue ( yue.chen2@hisoft.com ) Create on 2011-6-2
	 */
	private static List<ABaseTag> xml2Import(File file) {
		List<ABaseTag> importList = null;
		try {
			reader = factory.createXMLStreamReader(new FileReader(file));
			fileName = file.getName();
			importList = new ArrayList<ABaseTag>();
			while (reader.hasNext()) {
				switch (reader.getEventType()) {
				case XMLStreamReader.START_ELEMENT:
					String name = reader.getLocalName();
					if (name.equals(XMLTestCaseTag.HTML)) {
						importList.add(xml2Html());
					} else if (name.equals(XMLTestCaseTag.FUNCTION)) {
						importList.add(xml2Function());
					} else if (name.equals(XMLTestCaseTag.IMPORTXML)) {
						// tc.addOperate(xml2Import());
					} else if (name.equals(XMLTestCaseTag.VERIFY)) {
						importList.add(xml2Verify());
					} else if (name.equals(XMLTestCaseTag.ASSERT)) {
						importList.add(xml2Assert());
					} else if (name.equals(XMLTestCaseTag.CHOOSE)) {
						// tc.addOperate(xml2Choose());
					} else if (name.equals(XMLTestCaseTag.LOOP)) {

					} else if (name.equals(XMLTestCaseTag.TEST)) {

					} else if (name.equals(XMLTestCaseTag.TESTCASE)) {

					} else if (name.equals(XMLTestCaseTag.TEST_CASE_NAME)) {

					} else if (name.equals(XMLTestCaseTag.ANNOTATION)) {

					} else if (name.equals(XMLTestCaseTag.DESCRIPTION)) {

					} else if (name.equals(XMLTestCaseTag.CREATED)) {

					} else if (name.equals(XMLTestCaseTag.LAST_UPDATED)) {

					} else if (name.equals(XMLTestCaseTag.RECORDINFO)) {

					} else {
						logger.debug("xml2TestCaseObject unhandle tag: " + name);
					}
					break;
				case XMLStreamReader.END_ELEMENT:
					break;
				default:
					break;
				}
				if (reader.hasNext()) {
					reader.next();
				}// 获取下一个解析事件
			}
		} catch (FileNotFoundException e) {
			logger.error(e.getMessage(), e);
		} catch (XMLStreamException e) {
			logger.error(e.getMessage(), e);
		}
		return importList;
	}

	/**
	 * 
	 * <b> </b>
	 * 
	 * @throws XMLStreamException
	 * 
	 * @Author chenyue ( yue.chen2@hisoft.com ) Create on 2011-6-2
	 */
	private static Html xml2Html() throws XMLStreamException {
		Html html = new Html();
		html.setCommand(reader.getAttributeValue(null, XMLTestCaseTag.COMMAND));

		try {
			html.setTarget(DataProviderTool.getData(reader.getAttributeValue(null, XMLTestCaseTag.TARGET)));
			html.setValue(DataProviderTool.getData(reader.getAttributeValue(null, XMLTestCaseTag.VALUE)));
		} catch (XpathNotFoundException e) {
			logger.error("file: " + fileName + " line: " + reader.getLocation().getLineNumber() + " " + e.getMessage(), e);
		}
		html.setLineNumb(reader.getLocation().getLineNumber());
		while (reader.getEventType() != XMLStreamReader.END_ELEMENT) {
			if (reader.getEventType() == XMLStreamConstants.CHARACTERS) {
				if (reader.isWhiteSpace()) {
					html.setInfo("");
				} else {
					html.setInfo(reader.getText());
				}
				break;
			} else if (reader.hasNext()) {
				reader.next();
			}
		}
		return html;
	}

	/**
	 * 
	 * <b> </b>
	 * 
	 * @throws XMLStreamException
	 * 
	 * @Author chenyue ( yue.chen2@hisoft.com ) Create on 2011-6-3
	 */
	private static Function xml2Function() throws XMLStreamException {
		Function function = new Function();
		function.setCommand(reader.getAttributeValue(null, XMLTestCaseTag.COMMAND));
		try {
			function.setTarget(DataProviderTool.getData(reader.getAttributeValue(null, XMLTestCaseTag.TARGET)));
			function.setValue(DataProviderTool.getData(reader.getAttributeValue(null, XMLTestCaseTag.VALUE)));
		} catch (XpathNotFoundException e) {
			logger.error("file: " + fileName + " line: " + reader.getLocation().getLineNumber() + " " + e.getMessage(), e);
		}
		function.setLineNumb(reader.getLocation().getLineNumber());
		while (reader.getEventType() != XMLStreamReader.END_ELEMENT) {
			if (reader.getEventType() == XMLStreamConstants.CHARACTERS) {
				if (reader.isWhiteSpace()) {
					function.setInfo("");
				} else {
					function.setInfo(reader.getText());
				}
				break;
			} else if (reader.hasNext()) {
				reader.next();
			}
		}
		return function;
	}

	/**
	 * 
	 * <b> </b>
	 * 
	 * @Author chenyue ( yue.chen2@hisoft.com ) Create on 2011-6-17
	 */
	private static AssertVerifyType getAVT(String str) {
		AssertVerifyType avt = AssertVerifyType.EQUALS;
		if (CommonTool.isEmpty(str)) {
		} else {
			try {
				avt = AssertVerifyType.valueOf(str.toUpperCase());
			} catch (IllegalArgumentException e) {
				logger.error(e.getMessage() + " change to default");
				avt = AssertVerifyType.EQUALS;
			}
		}
		return avt;
	}

	/**
	 * 
	 * <b> </b>
	 * 
	 * @throws XMLStreamException
	 * 
	 * @Author chenyue ( yue.chen2@hisoft.com ) Create on 2011-6-2
	 */
	private static Verify xml2Verify() throws XMLStreamException {
		Verify verify = new Verify();
		try {
			verify.setExcepted(DataProviderTool.getData(reader.getAttributeValue(null, XMLTestCaseTag.EXPECTED)));
		} catch (XpathNotFoundException e) {
			logger.error("file: " + fileName + " line: " + reader.getLocation().getLineNumber() + " " + e.getMessage(), e);
		}
		verify.setAvt(getAVT(reader.getAttributeValue(null, XMLTestCaseTag.TYPE)));
		Boolean flag = true;
		while (reader.hasNext() && flag) {
			switch (reader.getEventType()) {
			case XMLStreamReader.START_ELEMENT:
				verify.setLineNumb(reader.getLocation().getLineNumber());
				String name = reader.getLocalName();
				if (name.equals(XMLTestCaseTag.HTML)) {
					verify.setVerify(xml2Html());
				} else if (name.equals(XMLTestCaseTag.FUNCTION)) {
					verify.setVerify(xml2Function());
				} else if (name.equals(XMLTestCaseTag.VERIFY)) {
				} else {
					logger.debug("xml2Verify unhandle tag: " + name);
				}
				break;
			case XMLStreamReader.END_ELEMENT:
				if (reader.getLocalName().equals(XMLTestCaseTag.VERIFY)) {
					flag = false;
				}
				break;
			default:
				break;
			}
			if (reader.hasNext()) {
				reader.next();
			}// 获取下一个解析事件
		}
		verify.setInfo(verify.getVerify().getInfo());
		return verify;
	}

	/**
	 * 
	 * <b> </b>
	 * 
	 * @throws XMLStreamException
	 * 
	 * @Author chenyue ( yue.chen2@hisoft.com ) Create on 2011-6-2
	 */
	private static Assert xml2Assert() throws XMLStreamException {
		Assert assert1 = new Assert();
		try {
			assert1.setExcepted(DataProviderTool.getData(reader.getAttributeValue(null, XMLTestCaseTag.EXPECTED)));
		} catch (XpathNotFoundException e) {
			logger.error("file: " + fileName + " line: " + reader.getLocation().getLineNumber() + " " + e.getMessage(), e);
		}
		assert1.setAvt(getAVT(reader.getAttributeValue(null, XMLTestCaseTag.TYPE)));
		Boolean flag = true;
		while (reader.hasNext() && flag) {
			switch (reader.getEventType()) {
			case XMLStreamReader.START_ELEMENT:
				assert1.setLineNumb(reader.getLocation().getLineNumber());
				String name = reader.getLocalName();
				if (name.equals(XMLTestCaseTag.HTML)) {
					assert1.setVerify(xml2Html());
				} else if (name.equals(XMLTestCaseTag.FUNCTION)) {
					assert1.setVerify(xml2Function());
				} else if (name.equals(XMLTestCaseTag.ASSERT)) {
				} else {
					logger.debug("xml2Assert unhandle tag: " + name);
				}
				break;
			case XMLStreamReader.END_ELEMENT:
				if (reader.getLocalName().equals(XMLTestCaseTag.ASSERT)) {
					flag = false;
				}
				break;
			default:
				break;
			}
			if (reader.hasNext()) {
				reader.next();
			}// 获取下一个解析事件
		}
		assert1.setInfo(assert1.getVerify().getInfo());
		return assert1;
	}

}
